<!--
 * Copyright 2019 ia-cloud project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-->

<script type="text/html" data-template-name="PLC MC">

  <!-- Connection config -->
  <div class="form-row">
    <label for="node-input-connectionConfig" style="width:150px"><i class="fa fa-link"></i> <span data-i18n="ia-cloud-fds.plc-mc-protocol.dstring" /> <span data-i18n="ia-cloud-fds.plc-mc-protocol.connection-config" /></label>
    <input type="text" id="node-input-connectionConfig" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.connection-config">
  </div>
  <!-- Name -->
  <div class="form-row">
    <label for="node-input-name" style="width:150px"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name" /></label>
    <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
  </div>

  <!-- Tab, ownself -->
  <div class="form-row">
    <ul style="min-width: 500px; margin-bottom: 20px;" id="node-config-ia-cloud-plc-mc-protocol-tabs"></ul>
  </div>

  <!-- Tab contents -->
  <div id="node-config-ia-cloud-plc-mc-protocol-tabs-content" style="min-height:150px;">

    <!-- Object Settings (starts) -->
    <div id="ia-cloud-plc-mc-protocol-tab-object-settings" style="display:none">
      <div class="form-row">
        <label for="node-input-objectKey" style="width:150px"><i class="fa fa-tag"></i> <span data-i18n="ia-cloud-fds.plc-mc-protocol.object-name" /></label>
        <input type="text" id="node-input-objectKey" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.this-object-name">
      </div>
      <div class="form-row">
        <label for="node-input-objectDescription" style="width:150px"><i class="fa fa-tag"></i> <span data-i18n="ia-cloud-fds.plc-mc-protocol.object-description" /></label>
        <input type="text" id="node-input-objectDescription" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.this-object-description">
      </div>
      <div class="form-row">
        <label for="node-input-instanceKey" style="width:150px"><i class="fa fa-tag"></i> <span data-i18n="ia-cloud-fds.plc-mc-protocol.instance-name" /></label>
        <input type="text" id="node-input-instanceKey" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.this-instance-name">
      </div>
    </div>
    <!-- Object Settings (ends) -->

    <!-- Data settings (starts) -->
    <div id="ia-cloud-plc-mc-protocol-tab-data-settings" style="display:none">
      <!-- Addresses : rows -->
      <div class="ia-cloud-fds-plc-mc-addresses">
      </div>
      <!-- Addresses : row-template -->
      <div style="display:none;" class="ia-cloud-plc-mc-addresses-row-template">
        <div class="form-block">
          <div class="form-row">
            <label style="width:40px"><i class="fa fa-hashtag"></i> <span class="ia-cloud-fds-plc-mc-address-seq">000</span></label>
            <input type="text"   style="width:30%;" class="data-name" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.data-name">
            <input type="text"   style="width:30%;" class="common-name" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.common-name">
            <input type="text"   style="width:20%;" class="unit" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.unit">
          </div>
          <div class="form-row">
            <select style="width:30%; margin-left: 40px;" class="device-no">
              <option value="" default data-i18n="ia-cloud-fds.plc-mc-protocol.select-device"></option>
              <optgroup data-i18n="[label]ia-cloud-fds.plc-mc-protocol.bit">
                <option value="M">M</option>
                <option value="X">X</option>
                <option value="Y">Y</option>
                <option value="CS">CS</option>
                <option value="TS">TS</option>
              </optgroup>
              <optgroup data-i18n="[label]ia-cloud-fds.plc-mc-protocol.number">
                <option value="CN">CN</option>
                <option value="TN">TN</option>
                <option value="D">D(number)</option>
                <option value="DFLOAT">D(float)</option>
              </optgroup>
              <optgroup data-i18n="[label]ia-cloud-fds.plc-mc-protocol.string">
                <option selected="selected" value="DSTR">D(string)</option>
              </optgroup>
            </select>
            <input type="text"   style="width:30%;" class="address-no"     data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.address-no">
            <input type="number" style="width:15%;" class="address-length" data-i18n="[placeholder]ia-cloud-fds.plc-mc-protocol.address-length" min="1" value="1">
            <a class="editor-button ia-cloud-fds-plc-mc-addresses-remove"><i class="fa fa-remove"></i></a>
          </div>
          <div style="display:none; margin-left: 40px;" class="form-number-edit-row">
            <select style="display:none; width:40%;" class="sign">
              <option value="signed" default data-i18n="ia-cloud-fds.plc-mc-protocol.signed"></option>
              <option value="unsigned" data-i18n="ia-cloud-fds.plc-mc-protocol.unsigned"></option>
            </select>
            <input type="checkbox" class="double" value="double"> <span data-i18n="ia-cloud-fds.plc-mc-protocol.double" />
          </div>
        </div>
      </div>
    </div>
    <!-- Data settings (ends) -->

  </div>

</script>

<script type="text/html" data-help-name="PLC MC">



</script>

<script type="text/javascript">

  RED.nodes.registerType('PLC MC', {
    category: 'iaCloud devices',
    color: 'rgb(231, 180, 100)',
    // align: 'right',
    defaults: {
      connectionConfig: { value: '', type: 'PLC MC config', required: true },
      name: { value: 'PLC MC protocol' },
      objectKey: { value: '' },
      objectDescription: { value: '' },
      instanceKey: { value: '' },
      addresses: { value: '' },
    },
    inputs: 1,
    outputs: 1,
    icon: 'bridge-dash.png',
    label() {
      return this.name || 'PLC MC protocol';
    },
    oneditprepare() {
      // Tab
      const tabs = RED.tabs.create({
        id: 'node-config-ia-cloud-plc-mc-protocol-tabs',
        onchange(tab) {
          $('#node-config-ia-cloud-plc-mc-protocol-tabs-content').children().hide();
          $("#" + tab.id).show();
        },
      });
      tabs.addTab({
        id: 'ia-cloud-plc-mc-protocol-tab-object-settings',
        label: this._('ia-cloud-fds.plc-mc-protocol.tab.object-settings'),
      });
      tabs.addTab({
        id: 'ia-cloud-plc-mc-protocol-tab-data-settings',
        label: this._('ia-cloud-fds.plc-mc-protocol.tab.data-settings'),
      });

      // Stack object name.
      const objectKey = this.objectKey || '';
      $('.node-input-objectKey').val(objectKey);
      // Stack rows.
      const addresses = this.addresses || [];
      addresses.push({});
      const $rowTemplate = $('.ia-cloud-plc-mc-addresses-row-template .form-block');
      const rows = addresses.map((address, index) => getNewRow(index + 1, address, $rowTemplate));
      $('.ia-cloud-fds-plc-mc-addresses').append(rows);
      setEventHandler();
    },
    oneditsave() {
      // Build array address mapping rows.
      const rows = Array.from($('.ia-cloud-fds-plc-mc-addresses .form-block')).map((row) => {
        const $row = $(row);
        const dev = $row.find('.device-no').val();
        let sign;
        let double;
        switch (dev) {
          case 'CN':
          case 'TN':
          case 'D':
          case 'DFLOAT':
            sign = $row.find('.sign').val();
            double = $row.find('.double').prop('checked');
            break;
          default: sign = 'signed';
        }
        return {
          name: $row.find('.data-name').val(),
          common: $row.find('.common-name').val(),
          unit: $row.find('.unit').val(),
          dev,
          addr: $row.find('.address-no').val(),
          len: $row.find('.address-length').val(),
          sign,
          double,
        };
      });
      // Remove last empty rows.
      while (rows.length !== 0 && !(rows.slice(-1)[0].name || rows.slice(-1)[0].unit || rows.slice(-1)[0].dev || rows.slice(-1)[0].addr || rows.slice(-1)[0].len)) {
        rows.pop();
      }
      this.addresses = rows;
    },
  });

  /** Put sequence numbers (1-based). */
  const refreshSequence = () => {
    $('.ia-cloud-fds-plc-mc-address-seq').each((index, element) => $(element).text(index + 1));
  };

  /** Returns a new row instance. */
  const getNewRow = (rowNumber, rowValues, $rowTemplate) => {
    if (!$rowTemplate) {
      $rowTemplate = $('.ia-cloud-plc-mc-addresses-row-template .form-block');
    }
    if (!rowValues) {
      rowValues = {};
    }

    const $newRow = $rowTemplate.clone();
    const { dev } = rowValues;
    $newRow.find('.ia-cloud-fds-plc-mc-address-seq').text(rowNumber);
    $newRow.find('.data-name').val(rowValues.name);
    $newRow.find('.common-name').val(rowValues.common);
    $newRow.find('.unit').val(rowValues.unit);
    $newRow.find('.device-no').val(dev);
    $newRow.find('.address-no').val(rowValues.addr);
    $newRow.find('.address-length').val(rowValues.len);
    $newRow.find('.sign').val(rowValues.sign || 'signed');
    $newRow.find('.double').prop('checked', rowValues.double);
    switch (dev) {
      case 'CN':
      case 'TN':
      case 'D':
        $newRow.find('.sign').show();
      case 'DFLOAT':
        $newRow.find('.form-number-edit-row').show();
    }
    return $newRow;
  };

  const setEventHandler = () => {
    // ----------------------------------------
    // display number edit row when device is number.
    $('.ia-cloud-fds-plc-mc-addresses').on('change', '.device-no', function () {
      const $thisBlock = $(this).parents('.form-block');
      const dev = $thisBlock.find('.device-no').val();
      $thisBlock.children('.form-number-edit-row')
        .each(function (idx, obj) {
          switch (dev) {
            case 'CN':
            case 'TN':
            case 'D':
              $(obj).find('.sign').show();
              $(obj).show();
              break;
            case 'DFLOAT':
              $(obj).find('.sign').hide();
              $(obj).show();
              break;
            default:
              $(obj).find('.sign').hide();
              $(obj).hide();
          }
        });
    });
    // ----------------------------------------
    // Duplicate rows when some edits happen in the last row.
    $('.ia-cloud-fds-plc-mc-addresses').on('change', 'input', function () {
      const $thisRow = $(this).parent('.form-row').parent('.form-block');
      const $lastRow = $('.ia-cloud-fds-plc-mc-addresses .form-block:last');
      // Is it the last row?
      if ($thisRow.is($lastRow)) {
        const rowNumber = Number($lastRow.find('.ia-cloud-fds-plc-mc-address-seq').text());
        getNewRow(rowNumber + 1).hide().insertAfter($lastRow).fadeIn(300);
      }
    });
    // ----------------------------------------
    // Remove clicked row.
    $('.ia-cloud-fds-plc-mc-addresses').on('click', '.ia-cloud-fds-plc-mc-addresses-remove', function () {
      const $thisRow = $(this).parent('.form-row').parent('.form-block');
      if ($thisRow.siblings().length === 0) {
        // Do not remove, clear last first row.
        $thisRow.find('.data-name').val('');
        $thisRow.find('.common-name').val('');
        $thisRow.find('.unit').val('');
        $thisRow.find('.device-no').val('');
        $thisRow.find('.address-no').val('');
        $thisRow.find('.address-length').val('');
        $thisRow.find('.sign').val('');
        $thisRow.find('.double').prop('checked', false);
      } else {
        // @see https://stackoverflow.com/questions/734554/jquery-fadeout-then-slideup
        $thisRow.fadeTo(150, 0.00, () => {
          $thisRow.slideUp(150, () => {
            $thisRow.remove();
            refreshSequence();
          });
        });
      }
    });
  };

</script>
